<template>
  <transition name="message-fade">
    <div
      class="lm-message"
      v-if="visible"
      :style="computedStyle"
      :class="computedClass"
    >
      <div class="lm-message-content">
        <span v-if="type">
          <lm-icon :name="computedIconName" size="15"></lm-icon>
        </span>
        {{ message }}
        <span class="close-btn" @click="closeMessage">
          <lm-icon name="times" size="15"></lm-icon>
        </span>
      </div>
    </div>
  </transition>
</template>

<script>
import { oneOf } from "../../utils/index";
export default {
  name: "LmMessage",
  props: {
    duration: {
      // 自动关闭时间
      type: Number,
      default: 3000,
    },
    autoClose: {
      // 是否开启自动关闭
      type: Boolean,
      default: true,
    },
    position: {
      // 位置
      type: String,
      default: "right",
    },
    message: {
      type: String,
      default: "我是message消息提示",
    },
    type: {
      validator(value) {
        return oneOf(value, ["info", "success", "warning", "error"]);
      },
      default: "success",
    },
  },
  data() {
    return {
      visible: false,
      verticalTop: 0,
      baseOffset: 16,
    };
  },
  computed: {
    // 计算样式
    computedStyle() {
      return {
        top: this.verticalTop + "px",
        ...(this.LR_POSITON && {
          [`${this.position}`]: `${this.baseOffset}px`,
        }),
        ...(this.CENTER_POSITION && {
          left: "50%",
          marginTop: this.baseOffset + "px",
          transform: "translateX(-50%)",
        }),
      };
    },
    // 计算类名
    computedClass() {
      return {
        [`lm-message--${this.type}`]: this.type,
      };
    },
    // 计算icon图标
    computedIconName() {
      const ICONS = {
        success: "check-circle",
        error: "times-circle",
        warning: "exclamation-circle",
        info: "info-circle",
      };
      return ICONS[this.type];
    },
    LR_POSITON() {
      return this.position === "right" || "left";
    },
    CENTER_POSITION() {
      return this.position === "center";
    },
  },
  mounted() {
    if (this.autoClose) {
      this.startTimer();
    }
    this.createElement();
  },
  beforeDestroy() {
    //   移除
    this.$el.parentNode.removeChild(this.$el);
  },
  destroyed() {},
  methods: {
    //   创建一个当前实例
    createElement() {
      this.visible = true;
      document.body.appendChild(this.$el);
    },
    // 关闭message
    closeMessage() {
      this.visible = false;
    },
    // 定时器
    startTimer() {
      let timer = setTimeout(() => {
        this.visible = false;
      }, this.duration);
      this.$once("hook:beforeDestory", () => {
        clearTimeout(timer);
        timer = null;
      });
    },
  },
  watch: {
    visible(newVal) {
      if (!newVal) {
        this.$el.addEventListener("transitionend", () => {
          this.$destroy();
        });
        this.$emit("close");
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.lm-message {
  width: 380px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  border-width: 1px;
  border-style: solid;
  border-color: #ebeef5;
  position: fixed;
  z-index: 99999;
  line-height: 20px;
  transition: top 0.5s;
  background-color: #edf2fc;
  padding: 15px 15px 15px 20px;
  display: flex;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  border-radius: 5px;
}

.close-btn {
  position: absolute;
  right: 10px;
  top: 10px;
  cursor: pointer;
}

.message-fade-enter,
.message-fade-leave-to {
  opacity: 0;
  transform: translateY(-100px);
}

.message-fade-enter-active,
.message-fade-leave-active {
  transition: opacity 0.5s, transform 0.5s;
}

.lm-message--success {
  background-color: #f0f9eb;
  border-color: #e1f3d8;
}

.lm-message--success .lm-message__content {
  color: #67c23a;
}

.lm-message--warning {
  background-color: #fdf6ec;
  border-color: #faecd8;
}

.lm-message--warning .lm-message__content {
  color: #e6a23c;
}

.lm-message--error {
  background-color: #fef0f0;
  border-color: #fde2e2;
}

.lm-message--error .lm-message__content {
  color: #f56c6c;
}

.lm-message--info .lm-message__content {
  color: #909399;
}
</style>